home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
tge129c.arj
/
SOURCE.ARJ
/
CLIP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-20
|
4KB
|
151 lines
/*****************************************************************************
* The Graphics Engine version 1.29ßC *
* *
* The Graphics Engine code and documentation are Copyright (c) 1993 *
* by Matthew Hildebrand. *
* *
* Unauthorised usage or modification of any or all of The Graphics *
* Engine is strictly prohibited. *
*****************************************************************************/
#include "tge.h"
/****
***** Initial data declarations
****/
#define X1 (*x1)
#define Y1 (*y1)
#define X2 (*x2)
#define Y2 (*y2)
struct endpoints
{
int x1, y1, x2, y2;
};
union outCodes
{
struct
{
unsigned code0 : 1; /* x<VIEWPORTULX */
unsigned code1 : 1; /* y<VIEWPORTULY */
unsigned code2 : 1; /* x>VIEWPORTLRX */
unsigned code3 : 1; /* y>VIEWPORTLRY */
} ocs;
int outcodes;
};
static void setOutCodes(union outCodes *ocu, int x, int y);
/****
***** Clip a line
****/
int TGE_clipLine(int *x1, int *y1, int *x2, int *y2)
{
union outCodes ocu1, ocu2;
int inside, outside;
int temp;
/* initialize 4-bit codes */
setOutCodes(&ocu1, X1, Y1);
setOutCodes(&ocu2, X2, Y2);
inside = ((ocu1.outcodes | ocu2.outcodes) == 0);
outside = ((ocu1.outcodes & ocu2.outcodes) != 0);
while (!outside && !inside)
{
if (ocu1.outcodes == 0) // swap endpoints if necessary so
{ // that (x1,y1) needs to be clipped
temp = X1; /* swap X1 and X2 */
X1 = X2;
X2 = temp;
temp = Y1; /* swap Y1 and Y2 */
Y1 = Y2;
Y2 = temp;
temp = ocu1.outcodes; /* swap ocu1 and ocu2 */
ocu1 = ocu2;
ocu2.outcodes = temp;
}
if (ocu1.ocs.code0) /* clip left */
{
Y1 += (int)((long)(Y2-Y1)*(VIEWPORTULX-X1)/(X2-X1));
X1 = VIEWPORTULX;
}
else if (ocu1.ocs.code1) /* clip above */
{
X1 += (int)((long)(X2-X1)*(VIEWPORTULY-Y1)/(Y2-Y1));
Y1 = VIEWPORTULY;
}
else if (ocu1.ocs.code2) /* clip right */
{
Y1 += (int)((long)(Y2-Y1)*(VIEWPORTLRX-X1)/(X2-X1));
X1 = VIEWPORTLRX;
}
else if (ocu1.ocs.code3) /* clip below */
{
X1 += (int)((long)(X2-X1)*(VIEWPORTLRY-Y1)/(Y2-Y1));
Y1 = VIEWPORTLRY;
}
setOutCodes(&ocu1, X1, Y1);
inside = ((ocu1.outcodes | ocu2.outcodes) == 0); /* update codes */
outside = ((ocu1.outcodes & ocu2.outcodes) != 0);
}
return (inside);
}
void setOutCodes(union outCodes *u, int x, int y)
{
u->outcodes = 0;
u->ocs.code0 = (x < VIEWPORTULX);
u->ocs.code1 = (y < VIEWPORTULY);
u->ocs.code2 = (x > VIEWPORTLRX);
u->ocs.code3 = (y > VIEWPORTLRY);
}
/****
***** Clip a filled rectangle
****/
int TGE_clipFilledRect(int *ulx, int *uly, int *lrx, int *lry)
{
int temp;
if (*ulx > *lrx) /* swap coords if necessary */
{
temp = *ulx;
*ulx = *lrx;
*lrx = temp;
}
if (*uly > *lry)
{
temp = *uly;
*uly = *lry;
*lry = temp;
}
if (*ulx<=VIEWPORTLRX && *uly<=VIEWPORTLRY && *lrx>=VIEWPORTULX &&
*lry>=VIEWPORTULY)
{
if (*ulx < VIEWPORTULX) /* clip to viewport boundaries */
*ulx = VIEWPORTULX;
if (*uly < VIEWPORTULY)
*uly = VIEWPORTULY;
if (*lrx > VIEWPORTLRX)
*lrx = VIEWPORTLRX;
if (*lry > VIEWPORTLRY)
*lry = VIEWPORTLRY;
return (1); /* at least partially within viewport */
}
else
return (0); /* entirely outside viewport */
}